// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

import * as fs from 'fs';
import * as path from 'path';

// 数据结构类型定义
interface DataNode {
    name: string;
    description?: string;
    children?: DataNode[];
    path?: string; // 节点路径
    isSearchResult?: boolean; // 是否为搜索结果
    params?: ParamDefinition[]; // API参数定义
}

// 参数定义
interface ParamDefinition {
    name: string;
    type: 'string' | 'number' | 'boolean' | 'enum';
    description: string;
    defaultValue?: string | number | boolean;
    options?: string[]; // 枚举类型的选项
}

// API计算结果
interface ApiResult {
    title: string;
    summary: string;
    details: Record<string, any>;
}

// 树节点
class TreeNode extends vscode.TreeItem {
    public children?: TreeNode[];
    
    constructor(
        public readonly data: DataNode,
        public readonly collapsibleState: vscode.TreeItemCollapsibleState,
        public readonly contextValue?: string
    ) {
        super(
            data.name,
            data.children?.length ? 
                vscode.TreeItemCollapsibleState.Collapsed : 
                vscode.TreeItemCollapsibleState.None
        );
        
        this.tooltip = data.description || data.name;
        this.description = data.description || '';
        
        if (data.isSearchResult) {
            this.iconPath = new vscode.ThemeIcon('check', new vscode.ThemeColor('editor.findMatchBackground'));
        }

        // 设置点击节点时触发的命令
        this.command = {
            command: 'dataManager.selectNode',
            title: '选择API项',
            arguments: [this] // 传递当前节点实例
        };
    }
    
    getFullPath(): string {
        return this.data.path || this.label as string;
    }

    hasParams(): boolean {
        return !!this.data.params && this.data.params.length > 0;
    }
}

// 数据提供者
class DataProvider implements vscode.TreeDataProvider<TreeNode> {
    private _onDidChangeTreeData = new vscode.EventEmitter<TreeNode | undefined | null | void>();
    readonly onDidChangeTreeData = this._onDidChangeTreeData.event;
    
    private rootNodes: TreeNode[] = [];
    private searchResults: TreeNode[] = [];
    private isSearchMode = false;

    constructor(private data: DataNode[]) {
        this.rootNodes = this.buildTreeNodes(data);
    }
    
    private buildTreeNodes(dataNodes: DataNode[], parentPath: string = ''): TreeNode[] {
        return dataNodes.map(node => {
            const nodePath = parentPath ? `${parentPath} > ${node.name}` : node.name;
            
            const treeNode = new TreeNode(
                { ...node, path: nodePath },
                node.children?.length ? 
                    vscode.TreeItemCollapsibleState.Collapsed : 
                    vscode.TreeItemCollapsibleState.None,
                node.children?.length ? 'hasChildren' : 'leaf'
            );
            
            if (node.children) {
                treeNode.children = this.buildTreeNodes(node.children, nodePath);
            }
            
            return treeNode;
        });
    }
    
    getTreeItem(element: TreeNode): vscode.TreeItem {
        return element;
    }
    
    async getChildren(element?: TreeNode): Promise<TreeNode[]> {
        if (this.isSearchMode && !element) {
            return this.searchResults;
        }
        
        if (!element) {
            return this.rootNodes;
        }
        
        return element.children || [];
    }
    
    search(query: string): DataNode[] {
        const results: DataNode[] = [];
        
        const searchRecursive = (nodes: DataNode[], parentPath: string = '') => {
            for (const node of nodes) {
                const currentPath = parentPath ? `${parentPath} > ${node.name}` : node.name;
                
                const isMatch = 
                    node.name.toLowerCase().includes(query.toLowerCase()) || 
                    (node.description?.toLowerCase().includes(query.toLowerCase()) || false);
                
                if (isMatch) {
                    results.push({ ...node, path: currentPath, isSearchResult: true });
                }
                
                if (node.children) {
                    searchRecursive(node.children, currentPath);
                }
            }
        };
        
        searchRecursive(this.data);
        return results;
    }
    
    highlightSearchResults(results: DataNode[]) {
        this.isSearchMode = true;
        this.searchResults = [];
        
        const markMatchingNodes = (nodes: TreeNode[]) => {
            for (const node of nodes) {
                const match = results.find(r => r.name === node.data.name && r.path === node.getFullPath());
                if (match) {
                    node.data.isSearchResult = true;
                    this.searchResults.push(node);
                }
                
                if (node.children) {
                    markMatchingNodes(node.children);
                }
            }
        };
        
        markMatchingNodes(this.rootNodes);
        this._onDidChangeTreeData.fire();
    }
    
    clearSearch() {
        this.isSearchMode = false;
        this.searchResults = [];
        
        const clearMarks = (nodes: TreeNode[]) => {
            for (const node of nodes) {
                node.data.isSearchResult = false;
                if (node.children) {
                    clearMarks(node.children);
                }
            }
        };
        
        clearMarks(this.rootNodes);
        this._onDidChangeTreeData.fire();
    }
    
    getAllNodes(): DataNode[] {
        const nodes: DataNode[] = [];
        
        const flattenNodes = (treeNodes: TreeNode[]) => {
            for (const node of treeNodes) {
                nodes.push(node.data);
                if (node.children) {
                    flattenNodes(node.children);
                }
            }
        };
        
        flattenNodes(this.rootNodes);
        return nodes;
    }

	findNodeByPath(path: string): TreeNode | undefined {
        const findRecursive = (nodes: TreeNode[] | undefined): TreeNode | undefined => {
            if (!nodes) {return undefined;}
            
            for (const node of nodes) {
                if (node.getFullPath() === path) {
                    return node;
                }
                
                const found = findRecursive(node.children);
                if (found) {
                    return found;
                }
            }
            
            return undefined;
        };
        
        return findRecursive(this.rootNodes);
    }
    
    getPathToNode(node: TreeNode): TreeNode[] {
        const path: TreeNode[] = [];
        let currentNode: TreeNode | undefined = node;
        
        while (currentNode) {
            path.unshift(currentNode);
            currentNode = this.findParentNode(currentNode);
        }
        
        return path;
    }
    
    private findParentNode(node: TreeNode): TreeNode | undefined {
        const findRecursive = (nodes: TreeNode[] | undefined): TreeNode | undefined => {
            if (!nodes) {return undefined;}
            
            for (const parent of nodes) {
                if (parent.children?.includes(node)) {
                    return parent;
                }
                
                const found = findRecursive(parent.children);
                if (found) {
                    return found;
                }
            }
            
            return undefined;
        };
        
        return findRecursive(this.rootNodes);
    }
}

// API计算器
class ApiCalculator {
    // 计算Tanh操作的临时空间
    static calculateTanhTmpSize(shape: number[], dataType: string, reuseSpace: boolean): ApiResult {
        // 计算元素数量
        const elementCount = shape.reduce((acc, dim) => acc * dim, 1);
        
        // 获取数据类型大小（字节）
        const typeSizeMap: { [key: string]: number } = {
            'float32': 4,
            'float16': 2,
            'int32': 4,
            'int16': 2,
            'int8': 1,
            'uint8': 1
        };
        
        const typeSize = typeSizeMap[dataType] || 4;
        
        // 基础临时空间大小（不考虑复用）
        const baseTmpSize = elementCount * typeSize;
        
        // 计算最大和最小临时空间
        let minTmpSize = reuseSpace ? 0 : baseTmpSize;
        let maxTmpSize = baseTmpSize;
        
        // 格式化结果
        const formatSize = (bytes: number): string => {
            if (bytes < 1024) return `${bytes} B`;
            if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`;
            if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
            return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
        };
        
        return {
            title: 'Tanh临时空间计算结果',
            summary: `最大临时空间: ${formatSize(maxTmpSize)}, 最小临时空间: ${formatSize(minTmpSize)}`,
            details: {
                '输入参数': {
                    'Shape': shape.join(','),
                    '数据类型': dataType,
                    '复用源操作数空间': reuseSpace
                },
                '计算详情': {
                    '元素数量': elementCount,
                    '数据类型大小(字节)': typeSize,
                    '基础临时空间大小': formatSize(baseTmpSize),
                    '最小临时空间': formatSize(minTmpSize),
                    '最大临时空间': formatSize(maxTmpSize)
                }
            }
        };
    }
}

// 搜索控制器
class SearchController {
    private searchInputBox: vscode.InputBox;
    private currentSearchTerm: string = '';
    
    constructor(
        private dataProvider: DataProvider,
        private treeView: vscode.TreeView<TreeNode>
    ) {
        this.searchInputBox = vscode.window.createInputBox();
        this.setupSearchBox();
    }
    
    private setupSearchBox() {
        this.searchInputBox.placeholder = '搜索API...';
        this.searchInputBox.title = 'API搜索';
        
        this.searchInputBox.buttons = [
            {
                iconPath: new vscode.ThemeIcon('clear-all'),
                tooltip: '清除搜索'
            }
        ];
        
        this.searchInputBox.onDidChangeValue(async (query) => {
            this.currentSearchTerm = query;
            this.performSearch(query);
        });
        
        this.searchInputBox.onDidAccept(() => {
            this.showQuickPickResults();
            this.searchInputBox.hide();
        });
        
        this.searchInputBox.onDidTriggerButton(() => {
            this.dataProvider.clearSearch();
            this.searchInputBox.value = '';
            this.currentSearchTerm = '';
        });
        
        this.searchInputBox.onDidHide(() => {
            // 保持实例，不销毁
        });
    }
    
    private performSearch(query: string) {
        if (!query.trim()) {
            this.dataProvider.clearSearch();
            return;
        }
        
        const results = this.dataProvider.search(query);
        this.dataProvider.highlightSearchResults(results);
        
        // 自动展开第一个匹配项
        if (results.length > 0) {
            this.revealFirstResult();
        }
    }
    
    private async revealFirstResult() {
        const children = await this.dataProvider.getChildren();
        if (children.length > 0) {
            await this.treeView.reveal(children[0], { expand: true });
        }
    }
    
    private async showQuickPickResults() {
        if (!this.currentSearchTerm.trim()) {
            return;
        }
        
        const allNodes = this.dataProvider.getAllNodes();
        const results = allNodes.filter(node => 
            node.name.toLowerCase().includes(this.currentSearchTerm.toLowerCase()) || 
            (node.description?.toLowerCase().includes(this.currentSearchTerm.toLowerCase()) || false)
        );
        
        if (results.length === 0) {
            vscode.window.showInformationMessage('没有找到匹配的API');
            return;
        }
        
        // 修复：确保detail和description不为undefined
        const items = results.map(item => ({
            label: item.name,
            description: item.description || '',
            detail: item.path || '',
            item
        }));
        
        const selected = await vscode.window.showQuickPick(items, {
            placeHolder: '选择一个API项',
            matchOnDescription: true,
            matchOnDetail: true
        });
        
        if (selected) {
            // 修复：确保detail不为undefined
            vscode.window.showInformationMessage(`已选择: ${selected.label} - ${selected.detail}`);
            await this.revealNodeInTree(selected.detail);
            
            // 如果节点有参数，提示输入参数并执行计算
            const node = this.dataProvider.findNodeByPath(selected.detail);
            if (node && node.hasParams()) {
                await this.promptAndExecuteApi(node);
            }
        }
    }
    
    public async promptAndExecuteApi(node: TreeNode) {
        if (!node.data.params) {return;}
        
        const inputValues: { [key: string]: any } = {};
        
        // 逐个提示输入参数
        for (const param of node.data.params) {

            if (param.type === 'enum' && param.options) {
                const quickPickItems = param.options.map(option => ({ label: option }));
                const selectedItem = await vscode.window.showQuickPick(quickPickItems, {
                    placeHolder: param.description,
                    title: `输入 ${param.name}`,
                    canPickMany: false,
                    ignoreFocusOut: true
                });

                // 处理用户取消输入
                if (selectedItem === undefined) {
                    return;
                }

                inputValues[param.name] = selectedItem.label;
                continue;
            }

            // 布尔类型处理保持不变
            if (param.type === 'boolean') {
                const options = ['true', 'false'];
                const selected = await vscode.window.showQuickPick(options, {
                    placeHolder: param.description,
                    title: `输入 ${param.name}`
                });
                
                if (selected === undefined) {
                    return;
                }
                
                inputValues[param.name] = selected.toLowerCase() === 'true';
                continue;
            }

            // 其他类型使用输入框
            const input = await vscode.window.showInputBox({
                prompt: param.description,
                title: `输入 ${param.name}`,
                value: param.defaultValue?.toString() || '',
                ignoreFocusOut: true
            });

            // 处理用户取消输入
            if (input === undefined) {
                return;
            }

            // 类型转换
            inputValues[param.name] = param.type === 'number' 
                ? parseFloat(input) 
                : input;
        }
        
        // 执行API计算
        this.executeApi(node, inputValues);
    }
    
    private executeApi(node: TreeNode, params: { [key: string]: any }) {
        if (node.data.name === 'GetTanhMaxMinTmpSize') {
            // 修复：确保shape参数有效
            const shapeInput = params['shape'] as string;
            if (!shapeInput) {
                vscode.window.showErrorMessage('shape参数不能为空');
                return;
            }
            
            // 解析shape参数
            const shape = shapeInput.split(',').map(s => parseInt(s.trim(), 10));
            if (shape.some(isNaN)) {
                vscode.window.showErrorMessage('shape参数格式不正确，请使用逗号分隔的数字');
                return;
            }
            
            const dataType = params['dataType'] as string;
            const reuseSpace = params['reuseSpace'] as boolean;
            
            // 计算结果
            const result = ApiCalculator.calculateTanhTmpSize(shape, dataType, reuseSpace);
            
            // 显示结果
            this.showResult(result);

            // 直接显示结果页
            this.showResultWebview(result);
        } else {
            vscode.window.showInformationMessage(`执行 ${node.data.name}，参数: ${JSON.stringify(params)}`);
        }
    }
    
    private showResult(result: ApiResult) {
        // 显示简要结果
        const actions = ['查看详情'];
        vscode.window.showInformationMessage(result.summary, ...actions)
            .then(selection => {
                if (selection === '查看详情') {
                    // 显示详情面板
                    this.showResultWebview(result);
                }
            });
    }
    
    // 优化后的showResultWebview方法，支持自动滚动和样式增强
    private showResultWebview(result: ApiResult) {
        const panel = vscode.window.createWebviewPanel(
            'apiResult',
            result.title,
            vscode.ViewColumn.One,
            {
                enableScripts: true,
                retainContextWhenHidden: true
            }
        );

        panel.webview.html = this.generateResultHtml(result);
    }

    // 增强的HTML生成方法，使用语义化标签和CSS变量
    private generateResultHtml(result: ApiResult): string {
        const formatDetails = (details: Record<string, any>, level: number = 0): string => {
            let html = '';
            const indent = '  '.repeat(level);
            const baseIndent = level * 20;
            
            for (const [key, value] of Object.entries(details)) {
                if (typeof value === 'object' && value !== null) {
                    html += `${indent}<section class="detail-section" style="padding-left: ${baseIndent}px;">
                                <h3 class="section-title">${key}</h3>
                                <div class="section-content">${formatDetails(value, level + 1)}</div>
                            </section>`;
                } else {
                    html += `${indent}<div class="detail-item">
                                <span class="item-key">${key}:</span>
                                <span class="item-value">${typeof value === 'object' ? JSON.stringify(value) : value}</span>
                            </div>`;
                }
            }
            
            return html;
        };

        return `<!DOCTYPE html>
        <html lang="zh-CN">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>${result.title}</title>
            <style>
                /* 基础样式 */
                body {
                    font-family: 'Segoe UI', sans-serif;
                    line-height: 1.6;
                    margin: 2rem;
                    transition: all 0.3s ease;
                }

                .header {
                    border-bottom: 3px solid;
                    margin-bottom: 2rem;
                }

                .title {
                    font-size: 2.2rem;
                    margin-bottom: 0.5rem;
                }

                .summary {
                    padding: 1.2rem;
                    border-radius: 8px;
                    margin: 1.5rem 0;
                    box-shadow: 0 2px 4px rgba(0,0,0,0.05);
                }

                .detail-section {
                    margin-bottom: 2rem;
                }

                .section-title {
                    font-size: 1.6rem;
                    border-left: 4px solid;
                    padding-left: 0.8rem;
                    margin-bottom: 1rem;
                }

                .detail-item {
                    display: grid;
                    grid-template-columns: 180px auto;
                    gap: 1rem;
                    margin-bottom: 0.8rem;
                }

                .item-key {
                    font-weight: 500;
                    white-space: nowrap;
                }

                /* 浅色主题 */
                .theme-light {
                    --primary-color: #2c3e50;
                    --secondary-color: #3498db;
                    --text-color: #333;
                    --light-text: #666;
                    --bg-color: #ffffff;
                    --light-bg: #f8f9fa;
                    --border-color: #eaeaea;
                }

                .theme-light body {
                    background-color: var(--bg-color);
                    color: var(--text-color);
                }

                .theme-light .header {
                    border-color: var(--primary-color);
                }

                .theme-light .title {
                    color: var(--primary-color);
                }

                .theme-light .summary {
                    background: var(--light-bg);
                }

                .theme-light .section-title {
                    color: var(--secondary-color);
                    border-color: var(--secondary-color);
                }

                .theme-light .item-key {
                    color: var(--light-text);
                }

                .theme-light .item-value {
                    color: var(--text-color);
                }

                /* 深色主题 */
                .theme-dark {
                    --primary-color: #90caf9;
                    --secondary-color: #42a5f5;
                    --text-color: #e0e0e0;
                    --light-text: #bdbdbd;
                    --bg-color: #1e1e1e;
                    --light-bg: #2d2d2d;
                    --border-color: #444444;
                }

                .theme-dark body {
                    background-color: var(--bg-color);
                    color: var(--text-color);
                }

                .theme-dark .header {
                    border-color: var(--primary-color);
                }

                .theme-dark .title {
                    color: var(--primary-color);
                }

                .theme-dark .summary {
                    background: var(--light-bg);
                }

                .theme-dark .section-title {
                    color: var(--secondary-color);
                    border-color: var(--secondary-color);
                }

                .theme-dark .item-key {
                    color: var(--light-text);
                }

                .theme-dark .item-value {
                    color: var(--text-color);
                }

                @media (max-width: 600px) {
                    .detail-item {
                        grid-template-columns: 1fr;
                    }
                }
            </style>
            <script>
                // 检测VS Code主题并应用相应的样式
                function detectTheme() {
                    const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
                    document.documentElement.classList.add(isDark ? 'theme-dark' : 'theme-light');
                    
                    // 监听主题变化
                    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
                        document.documentElement.classList.remove(e.matches ? 'theme-light' : 'theme-dark');
                        document.documentElement.classList.add(e.matches ? 'theme-dark' : 'theme-light');
                    });
                }
                
                // 页面加载时执行
                document.addEventListener('DOMContentLoaded', detectTheme);
            </script>
        </head>
        <body>
            <div class="header">
                <h1 class="title">${result.title}</h1>
            </div>
            <div class="summary">${result.summary}</div>
            
            ${formatDetails(result.details)}
        </body>
        </html>`;
    }

    
    private async revealNodeInTree(path: string) {
        const targetNode = this.dataProvider.findNodeByPath(path);
        
        if (targetNode) {
            const pathNodes = this.dataProvider.getPathToNode(targetNode);
            
            for (const node of pathNodes.slice(0, -1)) {
                await this.treeView.reveal(node, { expand: true, focus: false, select: false });
            }
            
            await this.treeView.reveal(targetNode, { expand: false, focus: true, select: true });
        } else {
            vscode.window.showWarningMessage('未能在树形视图中找到所选节点');
        }
    }
    
    showSearchBox() {
        this.searchInputBox.show();
    }
    
    dispose() {
        this.searchInputBox.dispose();
    }
}

// 激活插件
// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {

	// Use the console to output diagnostic information (console.log) and errors (console.error)
	// This line of code will only be executed once when your extension is activated
	console.log('Congratulations, your extension "ascendc-spatial-calculator" is now active!');

	// The command has been defined in the package.json file
	// Now provide the implementation of the command with registerCommand
	// The commandId parameter must match the command field in package.json
	const disposable = vscode.commands.registerCommand('ascendc-spatial-calculator.helloWorld', () => {
		// The code you place here will be executed every time your command is executed
		// Display a message box to the user
		vscode.window.showInformationMessage('Hello World from AscendC Spatial Calculator!');
	});

	context.subscriptions.push(disposable);

	// 加载数据文件
	const dataPath = path.join(context.extensionPath, 'resources', 'data.json');
    let data: DataNode[] = [];
    
    try {
        const rawData = fs.readFileSync(dataPath, 'utf8');
        data = JSON.parse(rawData) || [];
    } catch (error) {
        vscode.window.showErrorMessage(`读取数据文件失败: ${error}`);
        data = [];
    }
    
    // 创建树数据提供器
    const dataProvider = new DataProvider(data);

    // 注册视图
    const treeView = vscode.window.createTreeView('dataHighLevelApiListView', {
        treeDataProvider: dataProvider,
        showCollapseAll: true
    });

    // 创建搜索控制器
    const searchController = new SearchController(dataProvider, treeView);

    const searchCommand = vscode.commands.registerCommand('dataManager.search', async () => {
        const searchTerm = await vscode.window.showInputBox({
            placeHolder: '搜索API...',
            prompt: '输入搜索关键词'
        });
        
        if (searchTerm) {
            dataProvider.search(searchTerm);
            
            const allNodes = dataProvider.getAllNodes();
            const results = allNodes.filter(node => 
                node.name.toLowerCase().includes(searchTerm.toLowerCase()) || 
                (node.description?.toLowerCase().includes(searchTerm.toLowerCase()) || false)
            );
            
            if (results.length === 0) {
                vscode.window.showInformationMessage('没有找到匹配的API');
                return;
            }
            
            const items = results.map(item => ({
                label: item.name,
                description: item.description,
                detail: item.path,
                item
            }));
            
            const selected = await vscode.window.showQuickPick(items, {
                placeHolder: '选择一个API项',
                matchOnDescription: true,
                matchOnDetail: true
            });
            
            if (selected) {
                vscode.window.showInformationMessage(`已选择: ${selected.label} - ${selected.detail}`);

            }
        }
    });
    
    // 注册清除搜索命令
    const clearSearchCommand = vscode.commands.registerCommand('dataManager.clearSearch', () => {
        dataProvider.clearSearch();
        searchController.showSearchBox();
    });
    
    // 注册点击节点命令
    const selectNodeCommand = vscode.commands.registerCommand('dataManager.selectNode', (node: TreeNode) => {
        if (node) {
            // vscode.window.showInformationMessage(`选中: ${node.getFullPath()}`);
            
            // 如果节点有参数，提示输入参数
            if (node.hasParams()) {
                searchController.promptAndExecuteApi(node);
            }
        }
    });
    

    // 添加到订阅
    context.subscriptions.push(treeView, searchCommand, clearSearchCommand, selectNodeCommand,searchController);
}

// 停用插件
// This method is called when your extension is deactivated
export function deactivate() {}
